/// <reference path="../../../../phaser.d.ts" />
import Phaser from 'phaser'

var game;
export class Game {
  constructor() {

    // 实例
    this.Vue = null
  }
  // vue实例化后
  setVue(vue) {
    this.Vue = vue
    game = new Phaser.Game(config)
    startX = game.config.width + pipeW
    this.initStates()

    // 屏幕兼容 全屏
    var canvas = document.querySelector('canvas');
    var windowWidth = window.innerWidth;
    var windowHeight = window.innerHeight;
    var windowRatio = windowWidth / windowHeight;
    var gameRatio =  game.config.width / game.config.height;
    if (windowRatio < gameRatio) {
        canvas.style.width = windowWidth + 'px';
        canvas.style.height = (windowWidth / gameRatio) + 'px';
    } else {
        canvas.style.width = (windowHeight * gameRatio) + 'px';
        canvas.style.height = windowHeight + 'px';
    }

  }
  // 初始化场景
  initStates() {
    game.scene.add('loading', loading, true)
    game.scene.add('playing', playing)
    game.scene.add('fail', fail)
  }
}

var config = {
  type: Phaser.AUTO,
  width: 300,
  height: 500,
  parent: "flappyBird",
  physics: {
    default: 'arcade',
    arcade: {
      gravity: {
        y: 300
      },
      debug: false
    }
  },
}
var bg, road, flash;

class loading extends Phaser.Scene {
  constructor() {
    super({
      key: 'loading'
    })
  }
  preload() {
    let loadBar = this.add.text(40, this.game.config.height / 2, `正在加载资源0%`, {
      fontSize: '24px',
      fill: '#fff'
    })
    this.load.image('bg', require('../assets/Back1.png'))
    this.load.image('flash', require('../assets/Flash.png'))
    this.load.image('logo', require('../assets/Logo.png'))
    this.load.image('pipe1', require('../assets/Pipe1.png'))
    this.load.image('pipe2', require('../assets/Pipe2.png'))
    this.load.image('road', require('../assets/Road2.png'))

    this.load.spritesheet('bird', require('../assets/bird.png'), {
      frameWidth: 34,
      frameHeight: 24
    })
    this.load.spritesheet('bomb', require('../assets/Bomb.png'), {
      frameWidth: 128,
      frameHeight: 128
    })
    this.load.spritesheet('number', require('../assets/Number.png'), {
      frameWidth: 28,
      frameHeight: 36
    })

    // 加载完成事件
    this.load.on('progress', function (value) {
      let rate = Math.trunc(value * 100)
      loadBar.setText(`正在加载资源${rate}%`)
    })
    this.load.on('complete', function () {
      loadBar.destroy()
    })
  }
  create() {
    // 创建 背景与地面
    bg = this.add.tileSprite(0, 0, 300, 500, 'bg')
    bg.setOrigin(0, 0)

    road = this.add.tileSprite(0, 410, 300, 500, 'road')
    road.setOrigin(0, 0)


    flash = this.add.image(150, -50, 'flash')

    // 监听事件
    this.input.on('pointerdown', () => {
      this.input.off('pointerdown')
      flash.destroy()
      road.destroy()
      this.game.scene.start('playing')
    })

    // 动作
    this.anims.create({
      key: 'fly1',
      frames: this.anims.generateFrameNumbers('bird', {
        start: 0,
        end: 2
      }),
      frameRate: 10,
      repeat: 1
    })
    this.anims.create({
      key: 'fly2',
      frames: this.anims.generateFrameNumbers('bird', {
        start: 4,
        end: 6
      }),
      frameRate: 10,
      repeat: 1
    })
    this.anims.create({
      key: 'fly3',
      frames: this.anims.generateFrameNumbers('bird', {
        start: 8,
        end: 10
      }),
      frameRate: 10,
      repeat: 1
    })

  }
  update() {
    if (flash.y < 250) {
      flash.setY(flash.y + 2)
    }
    if (!over) {
      bg.tilePositionX += speed / 5
      road.tilePositionX += speed
    }
  }
}

var bird, pipes,birdFly;
var over = false;
var scoreText, score = 0;
var that;
var min = 160,
  between = [100, 200]
var pipeH = 320,
  pipeW = 52
var space = 150;
var startX = 0
var speed = 2;

class playing extends Phaser.Scene {
  constructor() {
    super({
      key: 'playing'
    })
  }
  createPipes(pipesX = startX) {
    let topY = Phaser.Math.Between(between[0], between[1]) - pipeH / 2
    let bottomY =  topY + min + pipeH 

    // 创建水管
    pipes.create(pipesX, topY, 'pipe1')
    pipes.create(pipesX, bottomY, 'pipe2')

    pipes.children.iterate(function (child) {
      child.body.allowGravity = false // 关闭重力
    })

    if (pipesX < (this.game.config.width * 2 )) {
      this.createPipes(pipesX + space)
    }
  }
  updatePipes(pipesX = startX) {
    let topY = Phaser.Math.Between(between[0], between[1]) - pipeH / 2
    let bottomY = topY + min + pipeH 
    let i = 0
    pipes.children.iterate(function (child) {
      child.body.reset(child.x - speed, child.y)
      if (child.body.x < (bird.x) && !child.sign) {
        child.sign = true
        score += 0.5
        scoreText.setText(score)
        if (score % 10 == 0) speed += 1
      } else if (child.body.x < -pipeW*2) {
        child.sign = false
        if (child.y < 100) {
          child.body.reset(pipesX, topY)
        } else {
          child.body.reset(pipesX, bottomY)
        }
      }
    })
  }

  create() {
    let that = this
    let flys = [[1,'fly1'],[4,'fly2'],[8,'fly3']]
    let i = Math.floor(Math.random()*flys.length+1)-1

    birdFly = flys[i][1]
    bird = this.physics.add.sprite(50, this.game.config.height / 2, 'bird',flys[i][0])
    
    bird.setCollideWorldBounds(true)

    pipes = this.physics.add.group()
    this.createPipes()

    scoreText = this.add.text(10, 10, score)
    scoreText.setFontSize(36)

    road = this.add.tileSprite(0, 410, 300, 500, 'road')
    road.setOrigin(0, 0)
    road = this.physics.add.existing(road, 'staticSprite')

    this.input.on('pointerdown', function () {
      if (over) return
      that.tweens.add({
        targets: bird,
        duration: 50,
        angle: -30,
      })
      bird.setVelocityY(-150)
      bird.anims.play(birdFly)
    })

    this.physics.add.overlap(bird, pipes, function (bird, pipe) {
      GameOver(that)
    }, null, true)
    this.physics.add.collider(bird, road, function (bird, road) {
      GameOver(that)
    }, null, true)
  }
  update() {
    if (!over) {
      if (bird.angle < 90) bird.angle += 2;
      this.updatePipes()
    }
  }
}

function GameOver(that) {
  if (over) return
  over = true
  bird.setTint(0xff0000)
  bird.allowGravity = false
  that.game.scene.start('fail')
}

function resetPipe(pipesX = startX) {
  let i = 0
  pipes.children.iterate(function (child) {
    let topY = Phaser.Math.Between(between[0], between[1]) - pipeH / 2
    let bottomY = topY + min + pipeH 
    child.sign = false
    if (child.y < 100) {
      child.body.reset(pipesX, topY)
    } else {
      child.body.reset(pipesX, bottomY)
    }
    if (++i % 2 == 0) pipesX += space
  })
}

function reset(that) {
  if (!over) return
  bird.clearTint()
  bird.setY(that.game.config.height / 2)
  resetPipe()

  let flys = [[0,'fly1'],[4,'fly2'],[8,'fly3']]
  let i = Math.floor(Math.random()*flys.length+1)-1
  birdFly = flys[i][1]
  bird.setFrame(flys[i][0])

  speed = 2
  score = 0
  scoreText.setText(score)
  bird.allowGravity = true
  over = false
}
class fail extends Phaser.Scene {
  constructor() {
    super({
      key: 'fail'
    })
  }
  create() {
    let that = this
    flash = this.add.image(150, -50, 'flash')

    this.input.on('pointerdown', function () {
      if (!over) return
      flash.destroy()
      that.input.off('pointerdown')
      reset(that)
      that.game.scene.resume('playing')
    })
  }
  update() {
    if (flash.y < 250) {
      flash.setY(flash.y + 2)
    }
  }
}
